#include <stdio.h>
#include <libusb.h>

int main()
{
    libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
    libusb_device_handle *dev_handle; //a device handle
    libusb_context *ctx = NULL; //a libusb session
    int r; //for return values
    ssize_t cnt; //holding number of devices in list
    r = libusb_init(&ctx); //initialize the library for the session we just declared
    if(r < 0)
    {
        printf("Init Error\n");
        return 1;
    }
    libusb_set_debug(ctx, 3); //set verbosity level to 3, as suggested in the documentation

    cnt = libusb_get_device_list(ctx, &devs); //get the list of devices
    if(cnt < 0) {
        printf("Get Device Error\n");
        return 1;
    }
    printf("Device in list\n");

    dev_handle = libusb_open_device_with_vid_pid(ctx, 0x1443, 1); //these are vendorID and productID I found for my usb device
    if(dev_handle == NULL)
        printf("Cannot open devie\n");
    else
        printf("Device Opened\n");
    libusb_free_device_list(devs, 1); //free the list, unref the devices in it

    unsigned char data[5]; //data to write
    data[0]='a';data[1]='b';data[2]='c';data[3]='d'; data[4]=0;//some dummy values

    int actual; //used to find out how many bytes were written
    if(libusb_kernel_driver_active(dev_handle, 0) == 1)
    { //find out if kernel driver is attached
        printf("Kerned Driver Active\n");
        if(libusb_detach_kernel_driver(dev_handle, 0) == 0) //detach it
            printf("Kernel Driver Detached\n");
    }
    r = libusb_claim_interface(dev_handle, 0); //claim interface 0 (the first) of device (mine had jsut 1)
    if(r < 0)
    {
        printf("Cannot claim the Interface\n");
        return 1;
    }
    printf("Claimed the Interface\nData->%s\nWriting data\n", data);
    
    r = libusb_bulk_transfer(dev_handle, (2 | LIBUSB_ENDPOINT_OUT), data, 4, &actual, 0); //my device's out endpoint was 2, found with trial- the device had 2 endpoints: 2 and 129
    if(r == 0 && actual == 4) //we wrote the 4 bytes successfully
        printf("Write ok\n");
    else
        printf("Write Error\n");
    
    r = libusb_release_interface(dev_handle, 0); //release the claimed interface
    if(r!=0) {
        printf("Cannot release the Interface\n");
        return 1;
    }
    printf("Released the Interface\n");

    libusb_close(dev_handle); //close the device we opened
    libusb_exit(ctx); //needs to be called to end the

    return 0;
}
